﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq;
using System.Reflection;

namespace DbUpdateManage
{
    public class NDbContext : DbContext
    {
        public NDbContext()
            //   : base("NDbContext")
            : base("name=TestEntities1")
        {
            //Configuration.AutoDetectChangesEnabled = false;
            //Configuration.ValidateOnSaveEnabled = false;
            //Configuration.LazyLoadingEnabled = false;
            //Configuration.ProxyCreationEnabled = false;

            // Database.SetInitializer(new CreateDatabaseIfNotExists<NDbContext>());//如果数据库不存在就新建数据库
            Database.SetInitializer<NDbContext>(new MigrateDatabaseToLatestVersion<NDbContext, ReportingDbMigrationsConfiguration>());
        }

        public static List<Type> Types = new List<Type>();
        public static void Register<T>() where T : class
        {

            Types.Add(typeof(T));
        }

        public static event Func<List<Type>> GetTypes;
        protected List<Type> OnGetTypes()
        {
            return GetTypes?.Invoke();
        }

        internal sealed class ReportingDbMigrationsConfiguration : DbMigrationsConfiguration<NDbContext>
        {
            public ReportingDbMigrationsConfiguration()
            {
                AutomaticMigrationsEnabled = true;//任何Model Class的修改将会更新DB
                AutomaticMigrationDataLossAllowed = true;
            }
        }

        //public DbSet<Customer> Customers { get; set; }
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            // modelBuilder.Entity<sys_config>();
            //注册1 事件方式传参
            var types = OnGetTypes();
            if (types != null)
            {
                foreach (var type in types)
                {
                    Register(modelBuilder, type);
                }
            }

            //方法2
            foreach (var type in Types)
            {
                Register(modelBuilder, type);
            }


            //方法3 反射
            //string assembleFileName = Assembly.GetExecutingAssembly().CodeBase.Replace("Detect.DLL", "Mapping.DLL").Replace("file:///", "");
            //string assembleFileName = Assembly.GetExecutingAssembly().CodeBase.Replace("file:///", "");
            //Assembly asm = Assembly.LoadFile(assembleFileName);
            //var typesToRegister = asm.GetTypes();

            types = AppDomain.CurrentDomain.GetAssemblies()
              .SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IModel))))
              .ToList();
            foreach (var type in types)
            {
                Register(modelBuilder, type);
            }
        }

        private void Register(DbModelBuilder modelBuilder, Type type)
        {
            MethodInfo method = modelBuilder.GetType().GetMethod("Entity");
            if (method != null)
            {
                method = method.MakeGenericMethod(new Type[] { type });
                method.Invoke(modelBuilder, null);
            }
        }

        //protected override void OnModelCreating(DbModelBuilder modelBuilder)
        //{


        //    //// modelBuilder.Configurations.Add(new sys_config2());
        //    // //string assembleFileName = Assembly.GetExecutingAssembly().CodeBase.Replace("Detect.DLL", "NFine.Mapping.DLL").Replace("file:///", "");
        //    string assembleFileName = Assembly.GetExecutingAssembly().CodeBase.Replace("file:///", "");
        //    Assembly asm = Assembly.LoadFile(assembleFileName);
        //    var typesToRegister = asm.GetTypes()
        //    .Where(type => !String.IsNullOrEmpty(type.Namespace))
        //     .Where(type => type.BaseType != null && type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>))
        //    //      .Where(type => type.BaseType != null && type.BaseType.IsGenericType)
        //    ;
        //    foreach (var type in typesToRegister)
        //    {
        //        dynamic configurationInstance = Activator.CreateInstance(type);
        //        modelBuilder.Configurations.Add(configurationInstance);
        //        //modelBuilder.Entity
        //    }

        //    //modelBuilder.Entity<sys_config>().HasTableAnnotation()

        //    base.OnModelCreating(modelBuilder);



        //}


    }
}
